#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//int n, m;
//const int N = 1010;
//int v[N], w[N];
//int f[N][N];
//int solution1()
//{
//    cin >> n >> m;
//    for (int i = 1; i <= n; i++)cin >> v[i] >> w[i];
//    for (int i = 0; i <= m; i++)f[0][i] = 0;//一件物品都没选 0-m的容积下价值都为0
//    for (int i = 1; i <= n; i++)
//    {
//        for (int j = 0; j <= m; j++)
//        {
//            f[i][j] = f[i - 1][j];
//            if (j >= v[i])f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);//在拿i-1件物品，其容量为j-vi时放入物品的最大值 
//        }
//    }
//    cout << f[n][m];
//} 

//2
int n, m;
const int N = 1010;
int v[N], w[N];
int f[N];
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)cin >> v[i] >> w[i];
    for (int i = 0; i <= m; i++)f[i] = 0;//一件物品都没选 0-m的容积下价值都为0
    for (int i = 1; i <= n; i++)
    {
        for (int j = m; j >= v[i]; j--)
        {
            f[j] = max(f[j], f[j - v[i]] + w[i]);//滚动数组优化，从后向前遍历，这样第一个的结果用到的是上一层的数据
        }
    }
    cout << f[m];
}
